package com.gjy.sentinel.core.demo;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 降级（熔断）
 *
 * @author gjy
 * @version 1.0
 * @since 2025-10-15 15:42:54
 */
public class DegradeDemo {

    private static final String RESOURCE = "RemoteCall";
    private static final Random RAND = new Random();

    /**
     * 模拟一次远程调用，耗时 30~120 ms，10% 概率抛异常
     * 通过 DegradeDemo.tryCall() 能感知是否被熔断（DegradeException）
     */
    public static boolean tryCall() {
        Entry entry = null;
        try {
            entry = SphU.entry(RESOURCE);
            // ------------------ 业务模拟 ------------------
            int cost = 30 + RAND.nextInt(100);
            TimeUnit.MILLISECONDS.sleep(cost);
            if (RAND.nextInt(10) < 2) {
                throw new RuntimeException("mock remote error");
            }
            System.out.println("[DegradeDemo] 正常返回，耗时 " + cost + "ms");
            return true;
        } catch (BlockException be) {
            // 触发熔断会抛 DegradeException（也是 BlockException 的子类）
            System.out.println("[DegradeDemo] 熔断阻塞 => " + be.getClass().getSimpleName());
            return false;
        } catch (Exception e) {
            // 业务异常需手动上报，以便 DegradeRule 统计异常比例/次数
            Tracer.trace(e);
            System.out.println("[DegradeDemo] 业务异常 => " + e.getMessage());
            return false;
        } finally {
            if (entry != null) entry.exit();
        }
    }

}
